<template>
  <div v-loading="currentEmpty.type === EmptyEnum.LOADING" class="empty-box" :element-loading-svg="LoadingSvg">
    <div v-if="isShowEmpty" class="empty-box_error">
      <el-empty
        v-bind="$slots" :image-size="props.imageSize" :description="currentEmpty.description"
        :class="props.emptyClass"
        :style="props.emptyStyle"
      >
        <template #image>
          <div class="empty-box__image">
            <img v-if="currentEmpty.src" :src="currentEmpty.src" alt="">
          </div>
        </template>
        <template #default>
          <slot name="footer" :type="currentEmpty.type" />
        </template>
      </el-empty>
    </div>
    <div class="empty-box_content" :class="{ 'is-hide': isShowEmpty }">
      <slot />
    </div>
  </div>
</template>

<script lang="ts" setup>
// 是否显示空状态
import { onMounted, ref, watch, withDefaults } from 'vue'
import { EmptyEnum, EmptyInfo, EmptyState, EmptyType } from './type'
import { ObjectUtil } from '@utils/object-util'
import { LoadingSvg } from '@assets/styles/loading'

const props = withDefaults(defineProps<{
  // 当前显示状态
  state: EmptyState,
  // 图片大小，type为code时也会影响状态码的文字大小
  imageSize?: number,
  // 自定义类样式
  emptyClass?: string | string[] | Record<string, boolean>,
  // 自定义样式
  emptyStyle?: string | Record<string, string>,
}>(), {
  imageSize: 120
})

onMounted(function () {
  updateStatus()
})

// 是否显示缺省
const isShowEmpty = ref(true)
// 当前缺省对象
const currentEmpty = ref<EmptyType>({})

// 更新状态
function updateStatus () {
  let emptyType: EmptyType['type']
  let tempEmpty: EmptyType = {}
  if (ObjectUtil.isBoolean(props.state) || ObjectUtil.isString(props.state)) {
    if (ObjectUtil.isBoolean(props.state)) {
      emptyType = props.state ? EmptyEnum.SUCCESS : EmptyEnum.EMPTY
    } else {
      emptyType = props.state
    }
    tempEmpty = statusConfig.get(emptyType) || tempEmpty
  } else {
    const type = props.state?.type || EmptyEnum.NONE
    emptyType = type
    const _tempEmpty = statusConfig.get(type)
    if (_tempEmpty) tempEmpty = ObjectUtil.copy(_tempEmpty)
    Object.assign(tempEmpty, props.state || {})
  }
  if (emptyType === EmptyEnum.SUCCESS) {
    currentEmpty.value.type = EmptyEnum.SUCCESS
    isShowEmpty.value = false
  } else {
    tempEmpty.type = emptyType
    currentEmpty.value = tempEmpty
    isShowEmpty.value = true
  }
}

const statusConfig = new Map<string, EmptyInfo>([
  ['Empty', { src: new URL('./images/empty.png', import.meta.url), description: '暂无数据' }],
  ['EmptyTip', { src: new URL('./images/empty-tip.png', import.meta.url), description: '暂无数据' }],
  ['EmptyVar', { src: new URL('./images/empty-var.png', import.meta.url), description: '当前无内容，请选择参数' }],
  ['Loading', { src: '', description: ' ' }],
  ['None', { src: '', description: ' ' }]
])

watch(() => props.state, updateStatus, { deep: true })
</script>

<style lang="scss">
.empty-box {
  position: relative;
}
.empty-box_content {
  width: 100%;
  //height: inherit;
  height: 100%;
  &.is-hide {
    opacity: 0;
  }
}
.empty-box_error {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 5;
  display: flex;
  justify-content: center;
  align-items: center;
  .empty-box__image {
    //opacity: .9;
    //filter: hue-rotate(215deg)
  }
}
</style>
